package cloud.xcan.angus.core.tester.interfaces.project;

import cloud.xcan.angus.core.tester.interfaces.project.facade.TemplateFacade;
import cloud.xcan.angus.core.tester.interfaces.project.facade.dto.template.TemplateAddDto;
import cloud.xcan.angus.core.tester.interfaces.project.facade.dto.template.TemplateImportDto;
import cloud.xcan.angus.core.tester.interfaces.project.facade.dto.template.TemplateUpdateDto;
import cloud.xcan.angus.core.tester.interfaces.project.facade.vo.template.TemplateListVo;
import cloud.xcan.angus.remote.ApiLocaleResult;
import cloud.xcan.angus.spec.experimental.IdKey;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

@Tag(name = "Template", description = "Template Management - APIs for creating, updating, deleting, and querying templates with quota management (max 200 custom templates)")
@Validated
@RestController
@RequestMapping("/api/v1/template")
public class TemplateRest {

  @Resource
  private TemplateFacade templateFacade;

  @Operation(summary = "Create template",
      description = "Create a new custom template with detailed configuration. Maximum 200 custom templates allowed.",
      operationId = "func:test:template:add")
  @ApiResponses(value = {
      @ApiResponse(responseCode = "201", description = "Test template created successfully"),
      @ApiResponse(responseCode = "400", description = "Maximum custom template quota exceeded (200 templates)")
  })
  @ResponseStatus(HttpStatus.CREATED)
  @PostMapping
  public ApiLocaleResult<IdKey<Long, Object>> add(@Valid @RequestBody TemplateAddDto dto) {
    return ApiLocaleResult.success(templateFacade.add(dto));
  }

  @Operation(summary = "Update custom template",
      description = "Update an existing custom template with partial modification support. System templates cannot be updated.",
      operationId = "func:test:template:update")
  @ApiResponses(value = {
      @ApiResponse(responseCode = "200", description = "Test template updated successfully"),
      @ApiResponse(responseCode = "404", description = "Test template not found"),
      @ApiResponse(responseCode = "400", description = "System template cannot be updated")
  })
  @PatchMapping
  public ApiLocaleResult<?> update(@Valid @RequestBody TemplateUpdateDto dto) {
    templateFacade.update(dto);
    return ApiLocaleResult.success();
  }

  @Operation(summary = "Delete custom template",
      description = "Delete a custom template from the system. System templates cannot be deleted.",
      operationId = "func:test:template:delete")
  @ApiResponses(value = {
      @ApiResponse(responseCode = "204", description = "Test template deleted successfully"),
      @ApiResponse(responseCode = "404", description = "Test template not found"),
      @ApiResponse(responseCode = "400", description = "System template cannot be deleted")
  })
  @ResponseStatus(HttpStatus.NO_CONTENT)
  @DeleteMapping("/{id}")
  public void delete(
      @Parameter(name = "id", description = "Test template identifier for deletion", required = true) @PathVariable("id") Long id) {
    templateFacade.delete(id);
  }

  @Operation(summary = "List all templates",
      description = "Retrieve list of all templates (both system and custom templates) without pagination",
      operationId = "func:test:template:list")
  @ApiResponses(value = {
      @ApiResponse(responseCode = "200", description = "Test template list retrieved successfully")
  })
  @GetMapping
  public ApiLocaleResult<List<TemplateListVo>> list() {
    return ApiLocaleResult.success(templateFacade.list());
  }

  @Operation(summary = "Import template",
      description = "Import a single template from Excel, CSV or JSON file. If a template with the same name already exists, import will be stopped.",
      operationId = "func:test:template:import")
  @ApiResponses(value = {
      @ApiResponse(responseCode = "200", description = "Template imported successfully"),
      @ApiResponse(responseCode = "400", description = "Invalid file format, template name already exists, or maximum template quota exceeded (200 templates)")
  })
  @ResponseStatus(HttpStatus.OK)
  @PostMapping(value = "/import", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
  public ApiLocaleResult<IdKey<Long, Object>> imports(
      @Parameter(content = @Content(mediaType = MediaType.MULTIPART_FORM_DATA_VALUE), schema = @Schema(type = "object")) @Valid TemplateImportDto dto) {
    return ApiLocaleResult.success(templateFacade.imports(dto));
  }

  @Operation(summary = "Export template",
      description = "Export a single template by ID to Excel, CSV or JSON format for backup or migration purposes",
      operationId = "func:test:template:export")
  @ApiResponses(value = {
      @ApiResponse(responseCode = "200", description = "Template exported successfully"),
      @ApiResponse(responseCode = "404", description = "Template not found")
  })
  @GetMapping(value = "/{id}/export")
  public ResponseEntity<org.springframework.core.io.Resource> export(
      @Parameter(name = "id", description = "Template identifier to export", required = true) @PathVariable("id") Long id,
      @Parameter(name = "format", description = "Export format: excel, csv, or json", example = "excel") @RequestParam(value = "format", defaultValue = "excel") String format,
      HttpServletResponse response) {
    return templateFacade.export(id, format, response);
  }
}
